home *** CD-ROM | disk | FTP | other *** search
/ 3D Games (Spidla) / 3dhry1.iso / mAz Lite 1.0 / move.wdl < prev    next >
Encoding:
Text File  |  2003-03-17  |  27.3 KB  |  964 lines

  1. // Template file v5.202 (02/20/02)
  2. ////////////////////////////////////////////////////////////////////////
  3. // File: move.wdl
  4. //        WDL prefabs for player movement
  5. ////////////////////////////////////////////////////////////////////////
  6. // Use:
  7. //        Include AFTER "movment.wdl"
  8. //
  9. //
  10. // Mod Date: 02/12/02 DCP
  11. //            player_move(): Increased distance (by 3) that entity must be "above"
  12. //        a passable surface to not swim.
  13. //
  14. // Mod Date: 02/20/02 DCP
  15. //            move_gravity(): Improved jumping code (no longer frame rate dependent)
  16.  
  17.  
  18. //@ Move Defines
  19.  
  20.  
  21. //@ Move Vars
  22.  
  23. //@ Move Actions
  24. //    Each of these three actions call 'player_move'
  25. //        player_walk -    player walk (basic move) action
  26. //        player_swim -    player swim action
  27. //        player_drive -    player drive action
  28.  
  29.  
  30. /////////////////////////////////////////////////////////////////////////
  31. // Desc: player walk action
  32. //
  33. //
  34. // no WED defined skills
  35. // uses _WALKFRAMES, _RUNFRAMES, _WALKSOUND
  36. ACTION player_walk
  37. {
  38.     MY._MOVEMODE = _MODE_WALKING;
  39.     MY._FORCE = 0.75;
  40.     MY._BANKING = -0.1;
  41.     MY.__JUMP = ON;
  42.     MY.__DUCK = ON;
  43.     MY.__STRAFE = ON;
  44.     MY.__BOB = ON;
  45.     MY.__TRIGGER = ON;
  46.  
  47.     player_move();
  48. }
  49.  
  50. /////////////////////////////////////////////////////////////////////////
  51. // Desc: player swim action
  52. //
  53. // uses _WALKFRAMES, _RUNFRAMES, _WALKSOUND
  54. ACTION player_swim
  55. {
  56.     MY._MOVEMODE = _MODE_SWIMMING;
  57.     MY._FORCE = 0.75;
  58.     MY._BANKING = 0;
  59.     MY.__JUMP = ON;
  60.     MY.__DUCK = ON;
  61.     MY.__STRAFE = OFF;
  62.     MY.__BOB = ON;
  63.  
  64.     player_move();
  65. }
  66.  
  67. /////////////////////////////////////////////////////////////////////////
  68. // Desc: player drive action
  69. //
  70. //
  71. // uses _WALKFRAMES, _RUNFRAMES, _WALKSOUND
  72. ACTION player_drive
  73. {
  74.     MY._MOVEMODE = _MODE_DRIVING;
  75.     MY._FORCE = 1.5;
  76.     MY._BANKING = 0.5;
  77.     MY.__SLOPES = ON;
  78.     MY.__TRIGGER = ON;
  79.  
  80.     player_move();
  81. }
  82.  
  83.  
  84.  
  85. //@ Move Function Protypes
  86. //ACTION player_move  - This is the main movement function, it handles the player movement
  87. //@@ player_move helper functions
  88. function move_gravity();    // handle movement on solids
  89. function wade_gravity();    // handle movement while wading
  90. function swim_gravity();    // handle movement in passables
  91. function scan_floor();        // scan surface under ME entity, sets values (also called from actor_move)
  92. function    fall_damage();        // return damage from falling
  93. function _player_force();    // set the values for force and aforce
  94.  
  95. function client_move();    // handles client entity movement
  96.  
  97.  
  98. function move_airborne();    // Airborne movement function
  99.  
  100.  
  101. //@ Move Functions
  102.  
  103. ////////////////////////////////////////////////////////////////////////
  104. // Desc: main player movement action
  105. //            called from 'player_walk', 'player_drive', & 'player_swim'
  106. //
  107. //
  108. // Mod Date: 02/12/02 DCP
  109. //                Increased distance that entity must be "above" a passable surface
  110. //            to not swim (previous vers allowed "Jesus Walk")
  111. //
  112. // uses _FORCE, _MOVEMODE, _BANKING, _WALKFRAMES, _RUNFRAMES, _WALKSOUND
  113. // uses __FALL, __WHEELS, __SLOPES, __JUMP, __DUCK, __STRAFE, __BOB, __TRIGGER
  114. ACTION player_move
  115. {
  116.     if(MY.CLIENT == 0) { player = ME; } // created on the server?
  117.  
  118.     MY._TYPE = _TYPE_PLAYER;
  119.     MY.ENABLE_SCAN = ON;    // so that enemies can detect me
  120.     if((MY.TRIGGER_RANGE == 0) && (MY.__TRIGGER == ON)) { MY.TRIGGER_RANGE = 32; }
  121.  
  122.     if(MY._FORCE == 0) {  MY._FORCE = 1.5; }
  123.     if(MY._MOVEMODE == 0) { MY._MOVEMODE = _MODE_WALKING; }
  124.     if(MY._WALKFRAMES == 0) { MY._WALKFRAMES = DEFAULT_WALK; }
  125.     if(MY._RUNFRAMES == 0) { MY._RUNFRAMES = DEFAULT_RUN; }
  126.     if(MY._WALKSOUND == 0) { MY._WALKSOUND = _SOUND_WALKER; }
  127.  
  128.     anim_init();      // init old style animation
  129.     perform_handle();    // react on pressing the handle key
  130.  
  131.  
  132.     // while we are in a valid movemode
  133.     while((MY._MOVEMODE > 0)&&(MY._MOVEMODE <= _MODE_STILL))
  134.     {
  135.         // if we are not in 'still' mode
  136.         if(MY._MOVEMODE != _MODE_STILL)
  137.         {
  138.             // Get the angular and translation forces (set aforce & force values)
  139.             _player_force();
  140.  
  141.             // find ground below (set my_height, my_floornormal, & my_floorspeed)
  142.             scan_floor();
  143.  
  144.             // if they are on or in a passable block...
  145.             if( ((ON_PASSABLE != 0) && (my_height_passable < (-MY.MIN_Z + 19)))    // upped from 16 to 19 (3q 'buffer')
  146.                 || (IN_PASSABLE != 0) )
  147.             {
  148.  
  149.                 // if not already swimming or wading...
  150.                 if((MY._MOVEMODE != _MODE_SWIMMING) && (MY._MOVEMODE != _MODE_WADING))
  151.                 {
  152.                       play_sound(splash,50);
  153.                       MY._MOVEMODE = _MODE_SWIMMING;
  154. //---                    actor_anim_transition(anim_swim_str);    //!!!!!
  155.  
  156.                     // stay on/near surface of water
  157.                     MY._SPEED_Z = 0;
  158.                   }
  159.  
  160.                 // if swimming...
  161.                   if(MY._MOVEMODE == _MODE_SWIMMING) // swimming on/in a passable block
  162.                 {
  163.                     if(ON_PASSABLE == ON) // && (IN_PASSABLE != ON)) -> Not need with version 4.193+
  164.                     {
  165.                         // check for wading
  166.                         temp.X = MY.X;
  167.                         temp.Y = MY.Y;
  168.                           temp.Z = MY.Z + MY.MIN_Z - my_height_passable;    // can my feet touch? (mod: 080801)
  169.                         trace_mode = IGNORE_ME + IGNORE_PASSABLE + IGNORE_PASSENTS;
  170.                         trace(MY.POS,temp);
  171.  
  172.                         if(RESULT > 0)
  173.                         {
  174.                             // switch to wading
  175.                             MY._MOVEMODE = _MODE_WADING;
  176.                               MY.TILT = 0;       // stop tilting
  177.                             my_height = RESULT + MY.MIN_Z;    // calculate wading height
  178. //---                            actor_anim_transition(anim_wade_str);    //!!!!!
  179.                         }
  180.  
  181.                      }
  182.  
  183.                 }// END swimming on/in a passable block
  184.                 else
  185.                 {    // not swimming
  186.  
  187.                     // if wading...
  188.                      if(MY._MOVEMODE == _MODE_WADING) // wading on/in a passable block
  189.                     {
  190.      /*
  191.                           // check for swimming
  192.                         temp.X = MY.X;
  193.                         temp.Y = MY.Y;
  194.                         temp.Z = MY.Z + MY.MIN_Z;    // can my feet touch?
  195.  
  196.                         //SHOOT MY.POS,temp;  // NOTE: ignore passable blocks
  197.                         trace_mode = IGNORE_ME + IGNORE_PASSABLE + IGNORE_PASSENTS;
  198.                         trace(MY.POS,temp);
  199.      */
  200.                         // NEW if model center is in the water switch to swimming mode
  201.                         result = content(MY.POS);
  202.                         if (result == content_passable)
  203.          //                if(RESULT == 0)
  204.                         {
  205.                             // switch to swimming
  206.                             MY._MOVEMODE = _MODE_SWIMMING;
  207.                         }
  208.                         else    // use SOLID surface for height (can't walk on water)
  209.                         {
  210.                               // get height to solid underwater surface
  211.                             temp.X = MY.X;
  212.                             temp.Y = MY.Y;
  213.                             temp.Z = MY.Z - 1000;//-- + MY.MIN_Z;    // can my feet touch?
  214.  
  215.                             trace_mode = IGNORE_SPRITES + IGNORE_ME + IGNORE_PASSABLE + IGNORE_PASSENTS;
  216.                             result = trace(MY.POS,temp);
  217.                               my_height = RESULT + MY.MIN_Z;    // calculate wading height
  218.                         }
  219.                     } // END wading on/in a passable block
  220.                 }
  221.  
  222.  
  223.  
  224.              } // END if they are on or in a passable block...
  225.             else  // not in or on a passable block
  226.             {
  227.                 // if wading or swimming while *not* on/in a passable block...
  228.                 if(   (MY._MOVEMODE == _MODE_SWIMMING)
  229.                     || ( (ON_PASSABLE == 0) && (MY._MOVEMODE == _MODE_WADING) )
  230.                   )
  231.                 {
  232.                     // get out of the water (go to walk mode)
  233.                     MY._MOVEMODE = _MODE_WALKING;
  234.                     MY.TILT = 0;       // stop tilting
  235.                 }
  236.              } // END not in or above water
  237.  
  238.  
  239.               // if he is on a slope, change his angles, and maybe let him slide down
  240.             if(MY.__SLOPES == ON)
  241.             {
  242.                 // Adapt the player angle to the floor slope
  243.                 MY_ANGLE.TILT = 0;
  244.                 MY_ANGLE.ROLL = 0;
  245.                 if((my_height < 10) && ((my_floornormal.X != 0) || (my_floornormal.Y != 0) ))
  246.                 {    // on a slope?
  247.                     // rotate the floor normal relative to the player
  248.                     MY_ANGLE.PAN = -MY.PAN;
  249.                     vec_rotate(my_floornormal,MY_ANGLE);
  250.                     // calculate the destination tilt and roll angles
  251.                     MY_ANGLE.TILT = -ASIN(my_floornormal.X);
  252.                     MY_ANGLE.ROLL = -ASIN(my_floornormal.Y);
  253.                 }
  254.                 // change the player angles towards the destination angles
  255.                 MY.TILT += 0.2 * ANG(MY_ANGLE.TILT-MY.TILT);
  256.                 MY.ROLL += 0.2 * ANG(MY_ANGLE.ROLL-MY.ROLL);
  257.             }
  258.             else
  259.             {
  260.                 // If the ROLL angle was not equal to zero,
  261.                 // apply a ROLL force to set the angle back
  262.                 //jcl 07-08-00 fix loopings on < 3 fps systems
  263.                 MY.ROLL -= 0.2*ANG(MY.ROLL);
  264.             }
  265.  
  266.             // Now accelerate the angular speed, and change his angles
  267.             // -old method- ACCEL    MY._ASPEED,aforce,ang_fric;
  268.             temp = max(1-TIME*ang_fric,0);     // replaced min with max (to eliminate 'creep')
  269.             MY._ASPEED_PAN  = (TIME * aforce.pan)  + (temp * MY._ASPEED_PAN);    // vp = ap * dt + max(1-(af*dt),0)  * vp
  270.             MY._ASPEED_TILT = (TIME * aforce.tilt) + (temp * MY._ASPEED_TILT);
  271.             MY._ASPEED_ROLL = (TIME * aforce.roll) + (temp * MY._ASPEED_ROLL);
  272.  
  273.               temp = MY._ASPEED_PAN * MY._SPEED_X * 0.05;
  274.             if(MY.__WHEELS)
  275.             {    // Turn only if moving ahead
  276.                 //jcl 07-03-00 patch to fix movement
  277.                 MY.PAN += temp * TIME;
  278.             }
  279.             else
  280.             {
  281.                 MY.PAN += MY._ASPEED_PAN * TIME;
  282.             }
  283.             MY.ROLL += (temp * MY._BANKING + MY._ASPEED_ROLL) * TIME;
  284.  
  285.             // the head angle is only set on the player in a single player system.
  286.             if (ME == player)
  287.             {
  288.                 head_angle.TILT += MY._ASPEED_TILT * TIME;
  289.                 //jcl 07-03-00 end of patcht
  290.  
  291.                 // Limit the TILT value
  292.                 head_angle.TILT = ang(head_angle.TILT);
  293.                 if(head_angle.TILT > 80) { head_angle.TILT = 80; }
  294.                 if(head_angle.TILT < -80) { head_angle.TILT = -80; }
  295.             }
  296.  
  297.             // disable strafing
  298.             if(MY.__STRAFE == OFF)
  299.             {
  300.                 force.Y = 0;    // no strafe
  301.             }
  302.  
  303.  
  304.             // if swimming...
  305.             if(MY._MOVEMODE == _MODE_SWIMMING)
  306.             {
  307.                  // move in water
  308.                   swim_gravity();
  309.             }
  310.             else // not swimming
  311.             {
  312.                 // if wading...
  313.                 if(MY._MOVEMODE == _MODE_WADING)
  314.                 {
  315.                     wade_gravity();
  316.                 }
  317.                 else // not swimming or wading (not in water)
  318.                 {
  319.                     // Ducking or crawling...
  320.                     if((MY._MOVEMODE == _MODE_DUCKING) || (MY._MOVEMODE == _MODE_CRAWLING))
  321.                     {
  322.                         if(force.Z >= 0)
  323.                         {
  324.                             MY._MOVEMODE = _MODE_WALKING;
  325.                         }
  326.                         else    // still ducking
  327.                         {
  328.                             // reduce height by ducking value
  329.                             my_height += duck_height;
  330.                         }
  331.  
  332.                     }
  333.                     else  // not ducking or crawling
  334.                     {
  335.                         // if we have a ducking force and are not already ducking or crawling...
  336.                         if((force.Z < 0) && (MY.__DUCK == ON))        // dcp 7/28/00 added __DUCK
  337.                         {
  338.                             // ...switch to ducking mode
  339.                             MY._MOVEMODE = _MODE_DUCKING;
  340.                             MY._ANIMDIST = 0;
  341.                             force.Z = 0;
  342.                         }
  343.                     }
  344.  
  345.                     // Decide whether the actor can jump or not. He can't if he is in the air
  346.                     if((jump_height <= 0)
  347.                         || (MY.__JUMP == OFF)
  348.                         || (my_height > 4)
  349.                         || (force.Z <= 0))
  350.                     {
  351.                         force.Z = 0;
  352.                     }
  353.  
  354.                     // move on land
  355.                     move_gravity();
  356.                 }  // END (not in water)
  357.             }// END not swimming
  358.  
  359.         } // END not in 'still' mode
  360.  
  361.         if(MY._MOVEMODE != _MODE_TRANSITION)
  362.         {
  363.             // animate the actor
  364.             actor_anim();
  365.         }
  366.  
  367.         // If I'm the only player, draw the camera and weapon with ME
  368.         if(client_moving == 0) { move_view(); }
  369.  
  370.         carry();        // action pointer used to carry items with the player (eg. a gun or sword)
  371.  
  372.         // Wait one tick, then repeat
  373.         wait(1);
  374.     }  // END while((MY._MOVEMODE > 0)&&(MY._MOVEMODE <= _MODE_STILL))
  375. }
  376.  
  377.  
  378.  
  379.  
  380. /////////////////////////////////////////////////////////////////////////
  381. // Desc: on ground movement action
  382. //            use when player is not swimming or wading
  383. //
  384. //
  385. // Mod Date: 02/20/02 DCP
  386. //                Improved jumping code (no longer frame dependent)
  387. function move_gravity()
  388. {
  389.     // Filter the forces and frictions dependent on the state of the actor,
  390.     // and then apply them, and move him
  391.  
  392.     // First, decide whether the actor is standing on the floor or not
  393.     if(my_height < 5)
  394.     {
  395.  
  396.         // Calculate falling damage
  397.          if((MY.__FALL == ON) && (MY._FALLTIME > fall_time))
  398.           {
  399.             MY._HEALTH -= fall_damage();        // take damage depending on fall_time
  400.          }
  401.         MY._FALLTIME = 0;     // reset falltime
  402.  
  403.         friction = gnd_fric;
  404.         if(MY._MOVEMODE == _MODE_DRIVING)
  405.         {
  406.             // Driving - less friction, less force
  407.             friction *= 0.3;
  408.             force.X *= 0.3;
  409.         }
  410.  
  411.         // reset absolute forces
  412.         absforce.X = 0;
  413.         absforce.Y = 0;
  414.         absforce.Z = 0;
  415.  
  416.         // If on a slope, apply gravity to draw him downwards:
  417.         if(my_floornormal.Z < 0.9)
  418.         {
  419.             // reduce ahead force because player force it is now deflected upwards
  420.             force.x *= my_floornormal.z;
  421.             force.y *= my_floornormal.z;
  422.             // gravity draws him down the slope
  423.             absforce.X = my_floornormal.x * gravity * slopefac;
  424.             absforce.Y = my_floornormal.y * gravity * slopefac;
  425.         }
  426.     }
  427.     else    // (my_height >= 5)
  428.     {
  429.         // airborne - reduce all relative forces
  430.         // to prevent him from jumping or further moving in the air
  431.         friction = air_fric;
  432.         //jcl 10-08-00
  433.         force.X *= 0.2; // don't set the force completely to zero, otherwise
  434.         force.Y *= 0.2; // player could be stuck on top of a non-wmb entity
  435.         force.Z = 0;
  436.  
  437.         absforce.X = 0;
  438.         absforce.Y = 0;
  439.         // Add the world gravity force
  440.         absforce.Z = -gravity;
  441.  
  442.         // only falling if moving downward (but not if ducking)
  443.         if( (MY._SPEED_Z <= 0) && ((MY._MOVEMODE != _MODE_DUCKING) && (MY._MOVEMODE != _MODE_CRAWLING)) )
  444.         {
  445.             MY._FALLTIME += TIME;   // add falling time
  446.         }
  447.     }
  448.  
  449.     // accelerate the entity relative speed by the force
  450.     // -old method- ACCEL    speed,force,friction;
  451.      // replaced min with max (to eliminate 'creep')
  452.     temp = max((1-TIME*friction),0);
  453.     MY._SPEED_X = (TIME * force.x) + (temp * MY._SPEED_X);    // vx = ax*dt + max(1-f*dt,0) * vx
  454.     MY._SPEED_Y = (TIME * force.y) + (temp * MY._SPEED_Y);    // vy = ay*dt + max(1-f*dt,0) * vy
  455.     MY._SPEED_Z = (TIME * absforce.z) + (temp * MY._SPEED_Z);
  456.  
  457.     // calculate relative distances to move
  458.     dist.x = MY._SPEED_X * TIME;      // dx = vx * dt
  459.     dist.y = MY._SPEED_Y * TIME;     // dy = vy * dt
  460.     dist.z = 0;                      // dz = 0  (only gravity and jumping)
  461.  
  462.     // calculate absolute distance to move
  463.     absdist.x = absforce.x * TIME * TIME;   // dx = ax*dt^2
  464.     absdist.y = absforce.y * TIME * TIME;   // dy = ay*dt^2
  465.     absdist.z = MY._SPEED_Z * TIME;         // dz = vz*dt
  466.  
  467.     // Add the speed given by the ground elasticity and the jumping force
  468.     if(my_height < 5)
  469.     {
  470.         // bring to ground level - only if slope not too steep
  471.         //jcl 10-08-00
  472.           if(my_floornormal.Z > slopefac/4)
  473.         {
  474.             absdist.z = -max(my_height,-10);
  475.         }
  476.  
  477.         // if we have a jumping force...
  478.         if(force.Z > 0)
  479.         {
  480.             MY._JUMPTARGET = jump_height - my_height;    // calculate jump delta
  481.  
  482.             // ...switch to jumping mode
  483.             MY._MOVEMODE = _MODE_JUMPING;
  484.             MY._ANIMDIST = 0;
  485.         }
  486.  
  487.         // If the actor is standing on a moving platform, add it's horizontal displacement
  488.         absdist.X += my_floorspeed.X;
  489.         absdist.Y += my_floorspeed.Y;
  490.     }
  491.  
  492.     // if we are still 'jumping'
  493.     if(MY._JUMPTARGET > 0)
  494.     {
  495.         // calculate velocity
  496.  
  497.         // predict the current speed required to reach the jump height
  498.          MY._SPEED_Z = sqrt((MY._JUMPTARGET)*2*gravity);
  499.  
  500.         // scale distance from jump (absdist.z) by movement_scale
  501.         absdist.z = MY._SPEED_Z * TIME * movement_scale;
  502.         MY._JUMPTARGET -= absdist.z;
  503.     }
  504.  
  505.     // Restrict the vertical distance to the maximum jumping height
  506.     // (scale jump_height by movement_scale)
  507.     if((MY.__JUMP == ON) && (absdist.z > 0) && (absdist.z + my_height > (jump_height * movement_scale)))
  508.     {
  509.         absdist.z = max((jump_height * movement_scale)- my_height,0);
  510.     }
  511.  
  512.     // Now move ME by the relative and the absolute speed
  513.     YOU = NULL;    // YOU entity is considered passable by MOVE
  514.  
  515.     vec_scale(dist,movement_scale);    // scale distance by movement_scale
  516.     // jcl: removed absdist scaling because absdist is calculated from external forces
  517.     //--- vec_scale(absdist,movement_scale);    // scale absolute distance by movement_scale
  518.  
  519.  
  520.     // Replaced the double MOVE with a single MOVE and a distance check
  521.     move_mode = ignore_you + ignore_passable + ignore_push + activate_trigger + glide;
  522.     result = ent_move(dist,absdist);
  523.     if(result > 0)
  524.     {
  525.         // only use the relative distance traveled (for animation)
  526.         my_dist = vec_length(dist);
  527.     }
  528.     else
  529.     {
  530.         // player is not moving, do not animate
  531.         my_dist = 0;
  532.     }
  533.  
  534.  
  535.     // Store the distance for player 1st person head bobbing
  536.     // (only for single player system)
  537.     if(ME == player)
  538.     {
  539.         player_dist += SQRT(dist.X*dist.X + dist.Y*dist.Y);
  540.     }
  541. }
  542.  
  543.  
  544. /////////////////////////////////////////////////////////////////////////
  545. // Desc: wading movement action
  546. //       this action should be called when the player is wading (_MODE_WADING)
  547. //
  548. function wade_gravity()
  549. {
  550.     // basic friction
  551.     friction = gnd_fric;
  552.  
  553.     MY._FALLTIME = 0;    // reset falltime (no falling damage in water)
  554.  
  555.     //adjust player force depending on depth of water
  556.     temp = (my_height_passable / max(1,-MY.MIN_Z));    // MY.min_z can be 0!!
  557.     if(temp < 0.1)    // minimum speed
  558.     {
  559.         temp = 0.1;
  560.     }
  561.     force.X *= temp;
  562.     force.Y *= temp;
  563.     force.Z *= temp;
  564.  
  565.     // reset absforce
  566.     absforce.X = 0;
  567.     absforce.Y = 0;
  568.     absforce.Z = 0;
  569.  
  570.     // If on a slope, apply gravity to draw him downwards:
  571.     if(my_floornormal.Z < 0.9)
  572.     {
  573.         // reduce ahead force because player force it is now deflected upwards
  574.         force.x *= my_floornormal.z;
  575.         force.y *= my_floornormal.z;
  576.         // gravity draws him down the slope (but only at 1/4 of above water)
  577.         absforce.X = my_floornormal.x * gravity * slopefac * 0.25;
  578.         absforce.Y = my_floornormal.y * gravity * slopefac * 0.25;
  579.     }
  580.  
  581.     // -old method- ACCEL    speed,force,friction;
  582.      // replaced min with max (to eliminate 'creep')
  583.     temp = max((1-TIME*friction),0);
  584.     MY._SPEED_X = (TIME * force.x) + (temp * MY._SPEED_X);    // vx = ax*dt + max(1-f*dt,0) * vx
  585.     MY._SPEED_Y = (TIME * force.y) + (temp * MY._SPEED_Y);    // vy = ay*dt + max(1-f*dt,0) * vy
  586.     MY._SPEED_Z = (TIME * absforce.z) + (temp * MY._SPEED_Z);
  587.  
  588.  
  589.     // calculate relative distances
  590.     dist.x = MY._SPEED_X * TIME;         // dx = vx * dt
  591.     dist.y = MY._SPEED_Y * TIME;     // dy = vy * dt
  592.     dist.z = 0;                      // dz = 0
  593.  
  594.     // calculate absolute distances
  595.     absdist.x = absforce.x * TIME * TIME;         // dx = ax * dt^2
  596.     absdist.y = absforce.y * TIME * TIME;     // dy = ay * dt^2
  597.     absdist.z = 0; // NO JUMPING WHILE WADING
  598.  
  599.      // Add the speed given by the ground elasticity
  600.      if(my_height < -5)
  601.     {
  602.         temp = my_height;
  603.         if(temp < -10)  { temp = -10; }
  604.          absdist.Z -= (temp - 5);
  605.     }
  606.     else
  607.     {
  608.          // Pull back down to the underwater surface
  609.         absdist.Z = max(-my_height,-gravity);
  610.  
  611.     }
  612.  
  613.     // Now move ME by the relative and the absolute speed
  614.     YOU = NULL;    // YOU entity is considered passable by MOVE
  615.     vec_scale(dist,movement_scale);    // scale distance by movement_scale
  616.     //--vec_scale(absdist,movement_scale);    // scale absolute distance by movement_scale
  617.     move_mode = ignore_you + ignore_passable + ignore_push + activate_trigger + glide;
  618.     result = ent_move(dist,absdist);
  619.  
  620.     // Store the distance covered, for animation
  621.     my_dist = RESULT;
  622.     // Store the distance for player 1st person head bobbing
  623.     // (only for single player system)
  624.     if(ME == player)
  625.     {
  626.         player_dist = my_dist;
  627.     }
  628. }
  629.  
  630.  
  631. /////////////////////////////////////////////////////////////////////////
  632. // Desc: gravity / buoyancy effect on the player in water (IN_PASSABLE)
  633. //       this action should be called when the player is swimming (_MODE_SWIMMING)
  634. //
  635. function swim_gravity()
  636. {
  637.     friction = water_fric;     // set friction to water friction
  638.  
  639.     MY._FALLTIME = 0;    // no falling damage in water
  640.  
  641.     // force.Z is used for diving/surfacing
  642.     if(force.Z == 0)
  643.     {
  644.         // level out player
  645.         if(MY.TILT < 0)
  646.         {
  647.             MY.TILT += 3 * TIME;
  648.             if(MY.TILT > 0)
  649.             {
  650.                 MY.TILT = 0;
  651.             }
  652.         }
  653.         else
  654.         {
  655.             if(MY.TILT > 0)
  656.             {
  657.                 MY.TILT -= 3 * TIME;
  658.                 if(MY.TILT < 0)
  659.                 {
  660.                     MY.TILT = 0;
  661.                 }
  662.              }
  663.         }
  664.     }
  665.     else
  666.     {
  667.         // surface player
  668.         if(force.Z > 0)
  669.         {
  670.             MY.TILT += 3 * TIME;
  671.             if(MY.TILT > 30)
  672.             {
  673.                 MY.TILT = 30;
  674.             }
  675.         }
  676.           else
  677.         {
  678.             // player diving
  679.             MY.TILT -= 3 * TIME;
  680.             if(MY.TILT < -30)
  681.             {
  682.                 MY.TILT = -30;
  683.             }
  684.         }
  685.     }
  686.  
  687. /*    NO absforce needed in this swim_gravity
  688.     // reset absolute forces
  689.       absforce.X = 0;
  690.     absforce.Y = 0;
  691.     absforce.Z = 0;
  692. */
  693.     // Swimming - rhythmic acceleration
  694.     force.X *= 0.5 + (0.25*walkwave);
  695.     force.Y *= 0.5;
  696.     force.Z *= 0.025;   // surface/diving force
  697.  
  698.  
  699.     // accelerate the entity relative speed by the force
  700.     // replaced min with max (to eliminate 'creep')
  701.     temp = max((1-TIME*friction),0);
  702.     MY._SPEED_X = (TIME * force.x) + (temp * MY._SPEED_X);    // vx = ax*dt - min(f*dt,1) * vx
  703.     MY._SPEED_Y = (TIME * force.y) + (temp * MY._SPEED_Y);    // vy = ay*dt - min(f*dt,1) * vy
  704.     MY._SPEED_Z = (TIME * force.z) + (temp * MY._SPEED_Z);    // vz = az*dt - min(f*dt,1) * vz
  705.  
  706.  
  707.     // calculate relative distances
  708.     dist.x = MY._SPEED_X * TIME;         // dx = vx * dt
  709.     dist.y = MY._SPEED_Y * TIME;     // dy = vy * dt
  710.     dist.z = MY._SPEED_Z * TIME;     // dz = vz * dt
  711.  
  712.  
  713. //jcl 07-22-00  scan_floor changed
  714.     if( (on_passable_ == ON) )
  715.     {
  716.         // reset absolute distance
  717.         absdist.x = 0;
  718.         absdist.y = 0;
  719.         absdist.z = 0;
  720.  
  721.         // if MY center (use passable height) is greater than the surface level...
  722.         if(((my_height_passable) > 5))// (MY.MIN_Z + 21)))   // 21 = 16 "hull" + 5 "float value"
  723.         {
  724.              // pull down to the surface of the water
  725.               absdist.Z -= min(gravity,my_height_passable);
  726.         }
  727.  
  728.  
  729.         // restrict climbing rotation on surface and check for edge...
  730.         if(MY.TILT > 5)
  731.         {
  732.             MY.TILT = 5;   // shallow climb
  733.  
  734.  
  735.             // If the user is near a solid edge and trying to swim up try to hop out
  736.             // scan ahead of ME
  737.             vec_set(vecFrom,MY.X);
  738.             vecFrom.X += (MY.MAX_X + 25) * cos(MY.PAN);
  739.             vecFrom.Y += (MY.MAX_X + 25) * sin(MY.PAN);
  740.             vec_set(vecTo,vecFrom);
  741.             vecFrom.Z += MY.MAX_Z;        // adjust this to adjust height
  742.  
  743.             trace_mode = IGNORE_ME + IGNORE_SPRITES + IGNORE_PASSENTS + IGNORE_MODELS + IGNORE_PASSABLE;
  744.             if( (trace(vecFrom,vecTo)) != 0)
  745.             {
  746.                 // hop out of water
  747.                 temp.X = 0; temp.Y = 0; temp.Z = MY.MAX_Z;
  748.                 //--move(ME,temp,NULLSKILL);
  749.                 move_mode = ignore_you + ignore_passable + ignore_push + activate_trigger + glide;
  750.                 ent_move(temp,NULLSKILL); // move up ..
  751.  
  752.                 temp.X = MY.MAX_X; temp.Z = 0;
  753.                 //--move(ME,temp,NULLSKILL);
  754.                 result = ent_move(temp,NULLSKILL);// ... and over
  755.  
  756.             }
  757.         }
  758.  
  759.         // Now move ME by the relative and the absolute speed
  760.         YOU = NULL;    // YOU entity is considered passable by MOVE
  761.         vec_scale(dist,movement_scale);    // scale distance by movement_scale
  762.         //    Removed absdist movement_scale because absdist is calculated from external forces
  763.         //---vec_scale(absdist,movement_scale);    // scale absolute distance by movement_scale
  764.         //--move(ME,dist,absdist);
  765.         move_mode = ignore_you + ignore_passable + ignore_push + activate_trigger + glide;
  766.         result = ent_move(dist,absdist);
  767.     }
  768.     else   // underwater
  769.     {
  770.          // NOTE: this is where we would add buoyancy (using absforce)
  771.         // right now we are assuming zero buoyancy
  772.  
  773.         // NOTE: this is where we could add the effect of currents (using absforce)
  774.  
  775.         // Now move ME by the relative and the absolute speed
  776.         YOU = NULL;    // YOU entity is considered passable by MOVE
  777.         vec_scale(dist,movement_scale);    // scale distance by movement_scale
  778.       //--    move(ME,dist,NULLSKILL);
  779.         move_mode = ignore_you + ignore_passable + ignore_push + activate_trigger + glide;
  780.         result = ent_move(dist,NULLSKILL);
  781.     }
  782.  
  783.  
  784.  
  785.     // Store the distance covered, for animation
  786.     my_dist = RESULT;
  787.     // Store the distance for player 1st person head bobbing
  788.     // (only for single player system)
  789.     if(ME == player)
  790.     {
  791.         player_dist += MY._SPEED_X;//SQRT(speed.X*speed.X + speed.Y*speed.Y);
  792.     }
  793. }
  794.  
  795. /////////////////////////////////////////////////////////////////////////
  796. // Desc: scan for a surface below the ME entity
  797. //       set my_floornormal vector to the normal of the surface
  798. //            set my_height to the distance between ME.MIN_Z and the surface
  799. //            set floorspeed to the X & Y speed of any platform ME is on.
  800. //            set on_passable_, in_passable_, and in_solid_ to the 'offset SONAR'
  801. //        values.
  802. //
  803. function scan_floor()
  804. {
  805.     // -old- SONAR    ME,4000;
  806. //jcl 1-14-01: forgotten IGNORE_SPRITES fixed
  807.     trace_mode = IGNORE_SPRITES + IGNORE_PASSENTS + IGNORE_MODELS + USE_BOX + ACTIVATE_SONAR;
  808.     vec_set(vecFrom,MY.x);
  809.     vec_set(vecTo,MY.x);
  810.     vecTo.z -= 4000;
  811.     my_height = trace(vecFrom,vecTo);  // this is the same as SONAR MY,distance;
  812.  
  813.     // if the first sonar shows we are in_passable or on_passable...
  814.     if((IN_PASSABLE == ON) || (ON_PASSABLE == ON))
  815.     {
  816.         // the entity can be completely or partially under water
  817. //--        vecFrom.z += 16;        // displace me upwards by the hull size - now my hull is outside the water
  818.         vecFrom.z += (MY.MAX_Z + MY.MIN_Z);// displace upwards by model's vertical center
  819.         trace_mode = IGNORE_SPRITES + IGNORE_PASSENTS + IGNORE_MODELS;
  820.         my_height_passable = trace(vecFrom,vecTo);
  821.  
  822.     }
  823.     else
  824.     {
  825.         my_height_passable = 0;
  826.     }
  827.  
  828.     // save SONAR values for later use
  829.     on_passable_ = ON_PASSABLE;
  830.     in_passable_ = IN_PASSABLE;
  831.     in_solid_ = IN_SOLID;
  832.  
  833.     my_floornormal.X = NORMAL.X;     // set my_floornormal to the normal of the surface
  834.     my_floornormal.Y = NORMAL.Y;
  835.     my_floornormal.Z = NORMAL.Z;
  836. //    my_height = RESULT;               // set my_height to the distance between entity's MIN_Z and surface
  837.  
  838.     my_floorspeed.X = 0;             // reset floorspeed to zero
  839.     my_floorspeed.Y = 0;
  840.  
  841.     // if the player is standing on a platform, move him with it
  842.     if(YOU != NULL)
  843.     {
  844.         if(YOUR._TYPE == _TYPE_ELEVATOR)
  845.         {
  846.             my_floorspeed.X = YOUR._SPEED_X;
  847.             my_floorspeed.Y = YOUR._SPEED_Y;
  848.             // Z speed is not necessary - this is done by the height adaption
  849.         }
  850.     }
  851. }
  852.  
  853.  
  854.  
  855. /////////////////////////////////////////////////////////////////////////
  856. // Desc: calculate the damage taken by a fall
  857. //
  858. //    Param: fall_time and MY must be set before calling
  859. //
  860. // Note: override this function if you want to use a different formula
  861. //
  862. // Called from 'move_gravity()'
  863. function    fall_damage()
  864. {
  865.     // calculate damage depending on _FALLTIME
  866.      return(0 + INT((MY._FALLTIME - fall_time) * 0));
  867. }
  868.  
  869.  
  870.  
  871. /////////////////////////////////////////////////////////////////////////
  872. // Desc: set force and aforce values
  873. //            these values come from _player_intentions (single player)
  874. //          or from the client (multiplayer)
  875. //
  876. //    Calls: _player_intentions
  877. //
  878. //    Called From: player_move()
  879. //
  880. function _player_force()
  881. {
  882.     // If the camera does not move itself
  883.     if (_camera == 0)
  884.     {
  885.         // multiplayer mode
  886.         if (client_moving)
  887.         {
  888.             // get forces from server
  889. //jcl 03/15/01
  890.             vec_set(force,MY._FORCE_X);
  891.             vec_set(aforce,MY._AFORCE_PAN);
  892.         }
  893.         else
  894.         {
  895.             // get forces from user input
  896.             _player_intentions();
  897.         }
  898.  
  899.         vec_scale(aforce,MY._FORCE);
  900.         vec_scale(force,MY._FORCE);
  901.     }
  902.     else
  903.     { // player controls camera - set actor forces to zero
  904.         vec_set(aforce,nullvector);
  905.         vec_set(force,nullvector);
  906.     }
  907. }
  908.  
  909.  
  910.  
  911. /////////////////////////////////////////////////////////////////////////
  912. // Desc: used in multiplayer (client/server) games
  913. //            set client_moving var to 1
  914. //            take user input use that to adjust the 'player' forces
  915. //            SEND player forces to the server
  916. //       move the camera
  917. //
  918. // Call: _player_intentions
  919. //            move_view
  920. function client_move()
  921. {
  922.     client_moving = 1;
  923.     while(1)
  924.     {
  925.         _player_intentions();// user key/mouse input sets force and aforce values
  926.  
  927.         // player created on the client?
  928.         if (player)
  929.         {
  930.             vec_set(player._FORCE_X,force);
  931.             vec_set(player._AFORCE_PAN,aforce);
  932.  
  933.         // send player forces to server
  934.             send_vec(player._FORCE_X);
  935.             send_vec(player._AFORCE_PAN);
  936.  
  937.         // move the camera
  938.             move_view();
  939.         }
  940.         wait(1);
  941.     }
  942. }
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949. /////////////////////////////////////////////////////////////////////
  950. // Desc: aitborne movement function
  951. function move_airborne()
  952. {
  953.     MY._POWER += 0.1*force.Z;
  954.     if(MY._POWER < 0) { MY._POWER = 0; }
  955.     if(MY._POWER > power_max) { MY._POWER = power_max; }
  956.     absforce.X = 0;
  957.     absforce.Y = 0;
  958.     absforce.Z = 0;
  959.  
  960.     friction = air_fric;
  961.     force.X = 0;
  962.     force.Y = 0;
  963.     force.Z = 0;
  964. }